package gupao.concurrency.simpledemo.service;

import gupao.concurrency.simpledemo.model.BizProcessResult;
import gupao.concurrency.simpledemo.model.UserInfo;
import gupao.concurrency.simpledemo.simulate.BizContext;
import gupao.concurrency.simpledemo.simulate.BizEngine;
import gupao.concurrency.simpledemo.simulate.TimeCostMock;
import gupao.concurrency.simpledemo.simulate.UserInfoMockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.Future;

@Service
@Slf4j
public class BizService {

    @Autowired
    private BizEngine bizEngine;

    @Autowired
    private UserInfoMockService userInfoMockService;

    public BizProcessResult<String> aggregateProcess(){
       Future<UserInfo> userInfo =  bizEngine.execute(() -> {
            String uid = BizContext.getUidFromContext();
           log.info("query user info by: {}", uid);
            return userInfoMockService.queryUserInfo(uid);
        });

       Future<String> result1 = bizEngine.execute(this::doBizProcess1);
       Future<String> result2 = bizEngine.execute(this::doBizProcess2);

        return BizProcessResult.create(get(userInfo), get(result1), get((result2)));
    }

    private String doBizProcess1(){
        String userId = BizContext.getUidFromContext();
        log.info("do some process 1 for {}", userId);
        //....
        TimeCostMock.mockTimeCost(700);
        return "result of process1 " + userId;
    }

    private String doBizProcess2(){
        String userId = BizContext.getUidFromContext();
        log.info("do some process 2 for {}", userId);
        //....
        TimeCostMock.mockTimeCost(800);
        return "result of process2 " + userId;
    }

    private <T> T get(Future<T> f){
        try {
            return f.get();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
